﻿using System;
using System.Collections.Specialized;
using System.Web.Mvc;
using ControleRepresentante.Logic.Models;
using ControleRepresentante.Logic.Repositories;
using ControleRepresentante.Logic.Statistics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WebSite.Controllers;
using WebSite.ViewModels.DetailsViewModels;
using Attribute = ControleRepresentante.Logic.Models.Attribute;

namespace ControleRepresentante.UnitTests.Controllers
{
    [TestClass]
    public class TransportadoraControllerTests : CRUDControllerTestScenarioBase<TransportadoraController, Transportadora, ITransportadoraRepository, StatisticsBase>
    {
        private Representante m_Representante;
        private const string Nome = "Transportadora";
        private const int Codigo = 1234;

        protected override TransportadoraController CreateController(bool isRepresentante = true)
        {
            this.LoginAsAdmin();
            Guid representanteId = this.CreateRepresentante("repre", true, "repreuser");
            m_Representante = RepositoryProvider.GetRepository<IRepresentanteRepository>().GetModelById(representanteId);
            this.CreateRepresentante("otherrepre", false, "other");
            if (isRepresentante)
            {
                this.Logout();
                this.LoginAs("repreuser");
            }
            return new TransportadoraController(RepositoryProvider, SessionConfiguration, ControllerExtensionProvider);
        }

        protected override Transportadora CreateModel()
        {
            return new Transportadora
            {
                Nome = Guid.NewGuid().ToString(),
                Representante = m_Representante,
            };
        }

        protected override ActionResult Create(TransportadoraController controller)
        {
            return controller.Create(Nome, CreateFormCollection());
        }

        private static FormCollection CreateFormCollection()
        {
            return new FormCollection(new NameValueCollection {{"codigo", Codigo.ToString()}});
        }

        protected override void VerifyModel(Transportadora model)
        {
            Assert.AreEqual(Nome, model.Nome);
            Assert.IsNotNull(model.TransportadoraJolitex);
            Assert.AreEqual(Codigo, model.TransportadoraJolitex.Codigo);
        }

        protected override ActionResult CreateEmptyFields(TransportadoraController controller)
        {
            return controller.Create(String.Empty, CreateFormCollection());
        }

        protected override void VerifyModelEmptyFields(Transportadora model)
        {
            Assert.AreEqual(String.Empty, model.Nome);
            Assert.IsNotNull(model.TransportadoraJolitex);
            Assert.AreEqual(Codigo, model.TransportadoraJolitex.Codigo);
        }

        protected override ActionResult CreateDuplicatedModel(TransportadoraController controller, Transportadora model)
        {
            return controller.Create(model.Nome, CreateFormCollection());
        }

        protected override void VerifyDuplicatedModel(Transportadora originalModel, Transportadora duplicatedModel)
        {
            Assert.AreEqual(originalModel.Nome, duplicatedModel.Nome);
            Assert.IsNotNull(duplicatedModel.TransportadoraJolitex);
            Assert.AreEqual(Codigo, duplicatedModel.TransportadoraJolitex.Codigo);
        }

        protected override ActionResult Edit(TransportadoraController controller)
        {
            return controller.Edit(Nome, CreateFormCollection());
        }

        protected override ActionResult EditEmptyFields(TransportadoraController controller)
        {
            return controller.Edit(String.Empty, CreateFormCollection());
        }

        protected override ActionResult EditDuplicatedModel(TransportadoraController controller, Transportadora modelToDuplicate)
        {
            return controller.Edit(modelToDuplicate.Nome, CreateFormCollection());
        }

        [TestMethod]
        [ExpectedException(typeof(LoginException))]
        public void TestTransportadorasNotAtivoRepresentante()
        {
            TransportadoraController transportadoraController = CreateController(false);
            this.LoginAs("other");
            transportadoraController.Index();
        }

        [TestMethod]
        public void TestCreateAndDeleteFullTransportadora()
        {
            this.LoginAsAdmin();
            this.CreateRepresentante("my representante", true, "user");
            this.Logout();

            this.LoginAs("user");
            this.CreateAttribute(AttributeType.Fabrica, "my attribute");
            Transportadora transportadora = new Transportadora { Nome = "nome" };
            transportadora.AddAttributeValue(new AttributeValue
            {
                Attribute = new Attribute { Name = "my attribute" },
                Value = "my attribute value"
            });
            transportadora.AddContato(new Contato
            {
                Tipo = ContatoType.FaxResidencial,
                Valor = "my contato valor",
                Observacao = "my contato observacao",
                Principal = true
            });
            transportadora.AddConta(new Conta
            {
                Agencia = "agencia",
                Banco = "banco",
                Numero = "numero",
                Observacao = "observacao",
                Principal = true
            });
            transportadora.AddEndereco(new Endereco
            {
                Bairro = "bairro",
                CEP = "cep",
                Cidade = "cidade",
                Complemento = "complemento",
                Estado = "estado",
                Numero = "numero",
                Observacao = "observacao",
                Rua = "rua",
                Tipo = EnderecoType.Residencial,
                Principal = true
            });
            Guid transportadoraId = this.CreateTransportadora(transportadora);
            this.DeleteTransportadora(transportadoraId);
        }

        [TestMethod]
        public void TestUnableToDeleteTransportadoraWithPedido()
        {
            this.LoginAsAdmin();
            this.CreateRepresentante("repre", true, "u");
            this.Logout();
            this.LoginAs("u");
            Guid vendedorId = this.CreateVendedor("vendedor");
            Guid clienteId = this.CreateCliente("nome", vendedorId);
            Guid transportadoraId = this.CreateTransportadora("transportadora");
            Guid fabricaId = this.CreateFabrica("fabrica");
            this.CreatePedido(vendedorId, clienteId, transportadoraId, fabricaId);
            using (TransportadoraController controller = new TransportadoraController(RepositoryProvider, SessionConfiguration, ControllerExtensionProvider))
            {
                ActionResult actionResult = controller.Delete(transportadoraId);
                Assert.IsInstanceOfType(actionResult, typeof(ViewResult));
                ViewResult viewResult = (ViewResult)actionResult;
                Assert.IsInstanceOfType(viewResult.Model, typeof(DetailsViewModel));
                DetailsViewModel detailsViewModel = (DetailsViewModel)viewResult.Model;
                Assert.IsNotNull(detailsViewModel.Message);
            }
        }
    }
}
